package demo.hdz.mediacodecdecode.filter;

import android.content.Context;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;

import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

/**
 * @author hdz
 * @date 2022/05/28 17:52
 * <p>
 * 设置饱和度、亮度、曝光度、对比度
 */
public class NormalFilter extends BaseFilter {

    /**
     * 顶点坐标
     * (x,y,z)
     */
    private static final float[] VERTEX_COORDINATE = {
            //右上
            1f, 1f, 0f,

            //右下
            1f, -1f, 0f,

            //左上
            -1f, 1f, 0f,

            //左下
            -1f, -1f, 0f
    };

    /**
     * 纹理坐标
     * (s,t)
     */
    private static final float[] TEXTURE_COORDINATE = {
            1f, 1f,
            1f, 0f,
            0f, 1f,
            0f, 0f
    };

    /**
     * 坐标索引
     */
    private static final short[] COORDINATE_INDEX = {
            //右上三角形
            0, 1, 2,

            //左下三角形
            1, 2, 3
    };

    private FloatBuffer mVertexCoordinateBuffer;
    private FloatBuffer mTextureCoordinateBuffer;
    private ShortBuffer mCoordinateIndexBuffer;
    private int aPositionLocation = -1;
    private int aTextureCoordLocation = -1;
    private int uTextureMatrixLocation = -1;
    private int uTextureSamplerLocation = -1;


    /**
     * 默认：1
     */
    private float saturation = 1.0f;
    private int saturationLocation = -1;

    /**
     * 默认：0
     */
    private float exposure = 0.0f;
    private int exposureLocation = -1;

    /**
     * 范围：-1~1
     * 默认：0
     */
    private float brightness = 0.0f;
    private int brightnessLocation = -1;

    /**
     * 默认：1
     */
    private float contrast = 1.0f;
    private int contrastLocation = -1;
    private boolean bSet = true;

    public NormalFilter(Context context) {
        super(context, "shader/v_normal.frag", "shader/f_normal.frag");
    }

    public NormalFilter(Context context, String v, String f) {
        super(context, v, f);
    }

    @Override
    public void init() {
        mVertexCoordinateBuffer = createBuffer(VERTEX_COORDINATE);
        mTextureCoordinateBuffer = createBuffer(TEXTURE_COORDINATE);
        mCoordinateIndexBuffer = createBuffer(COORDINATE_INDEX);
        int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vShader.trim());
        int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fShader.trim());
        int mShaderProgram = linkProgram(vertexShader, fragmentShader);

        aPositionLocation = GLES20.glGetAttribLocation(mShaderProgram, "aPosition");
        aTextureCoordLocation = GLES20.glGetAttribLocation(mShaderProgram, "aTextureCoordinate");
        uTextureMatrixLocation = GLES20.glGetUniformLocation(mShaderProgram, "uTextureMatrix");
        uTextureSamplerLocation = GLES20.glGetUniformLocation(mShaderProgram, "uTextureSampler");

        //设置饱和度、亮度、曝光度、对比度
        saturationLocation = GLES20.glGetUniformLocation(mShaderProgram, "saturation");
        brightnessLocation = GLES20.glGetUniformLocation(mShaderProgram, "brightness");
        exposureLocation = GLES20.glGetUniformLocation(mShaderProgram, "exposure");
        contrastLocation = GLES20.glGetUniformLocation(mShaderProgram, "contrast");

        GLES20.glEnableVertexAttribArray(aPositionLocation);
        GLES20.glVertexAttribPointer(aPositionLocation, 3, GLES20.GL_FLOAT, false, 0, mVertexCoordinateBuffer);
        GLES20.glEnableVertexAttribArray(aTextureCoordLocation);
        GLES20.glVertexAttribPointer(aTextureCoordLocation, 2, GLES20.GL_FLOAT, false, 0, mTextureCoordinateBuffer);
    }

    @Override
    public void drawFrame(int textureId, float[] transformMatrix) {
        GLES20.glActiveTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES);
        GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId);
        GLES20.glUniform1i(uTextureSamplerLocation, 0);
        GLES20.glUniformMatrix4fv(uTextureMatrixLocation, 1, false, transformMatrix, 0);

        if (bSet) {
            //设置饱和度、亮度、曝光度、对比度
            GLES20.glUniform1f(saturationLocation, saturation);
            GLES20.glUniform1f(brightnessLocation, brightness);
            GLES20.glUniform1f(exposureLocation, exposure);
            GLES20.glUniform1f(contrastLocation, contrast);
            bSet = true;
        }

        GLES20.glDrawElements(GLES20.GL_TRIANGLES, COORDINATE_INDEX.length, GLES20.GL_UNSIGNED_SHORT, mCoordinateIndexBuffer);
    }

    @Override
    public void setParameter(String key, int value) {
        super.setParameter(key, value);
        bSet = true;
        if ("saturation".equals(key)) {
            saturation = value / 10f - 4;
        } else if ("brightness".equals(key)) {
            brightness = value / 50f - 1;
        } else if ("exposure".equals(key)) {
            exposure = value / 10f - 5;
        } else if ("contrast".equals(key)) {
            contrast = value / 10f - 4;
        }
    }

    @Override
    public void release() {
        bSet = false;
    }
}
